home *** CD-ROM | disk | FTP | other *** search
/ Archive Magazine CD 1995 / Archive Magazine CD 1995.iso / discs / prog_disc / volume_5 / issue_12 / econet / RISCiX / np_c < prev   
Encoding:
Text File  |  1990-10-01  |  7.6 KB  |  307 lines

  1. /* > np 
  2.  * (C) Alan Williams 1990
  3.  * Source file for a program to copy stdin to an Econet printer server
  4.  * in 80 byte chunks.  
  5.  * 
  6.  * The idea is that you can use it as a pipe end.  For example
  7.  *  $ cat file | netprint
  8.  * will print the file on an Econet printer server.
  9.  * One optional parameter is permited.  That is the Econet address of the 
  10.  * server.  Acceptable syntax include net.station station and a name.
  11.  * For example 1.150, 235, and Laser2 will all work.
  12.  * The name form is prefered as it will error faster if the server is not
  13.  * free.
  14.  *
  15.  * This program prefers to have public read access to /dev/cmos.
  16.  * root may have to set this otherwise 0.235 will be assumed. 
  17.  *
  18.  *
  19.  * Started 1pm 15/9/1990.
  20.  * Worked first 4:30pm 16/9/1990
  21.  * A little more on 17/9/1990 ( started on the /dev/cmos bit.)
  22.  * A little more on 18/9/1990 ( it's not that easy.....)
  23.  * did some work on the printer poll bit instead.
  24.  * A little more on 1/10/1990 ( More work on /dev/cmos bit.)
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <strings.h>
  29. #include "sys/ioctl.h"
  30. #include "dev/econet.h"
  31.  
  32. unsigned char buffer[80];
  33. int bufferptr;
  34. int h,i;
  35. int seq;
  36.  
  37. struct netaddr {
  38.     unsigned char station;
  39.     unsigned char net;
  40. ;
  41.  
  42. struct netaddr server;
  43.  
  44. void quithandler() {
  45.     /*  Intended to be called on close down.  It should free ports and close
  46.         down gracefully.
  47.      */
  48.     if (h!=0) close(h);
  49. }
  50.  
  51. void error(char *s){
  52.     printf("%s\n",s);
  53.     quithandler();
  54.     exit(1);
  55. }
  56.  
  57. int claimeconetport(int port,int h){
  58.     return(ioctl(h,ECOCLAIMPORT,&port));
  59. }
  60.  
  61. void getserverbyname(char *s)
  62. {
  63.     int rc;
  64.     struct eco_op tx,rp;
  65.     if (strlen(s) >6 ) error("netprint: server name too long.");
  66.     strcpy(buffer,"      ");
  67.     strcpy(buffer,s);
  68.     buffer[strlen(s)]=' ';
  69.     buffer[6]=0x01;
  70.     buffer[7]=0x00;
  71.  
  72.     tx.eco_tx_data_ptr = (int) buffer;
  73.     tx.eco_tx_data_length = 8;
  74.     tx.eco_station = 0xFF;
  75.     tx.eco_net     = 0xFF;
  76.     tx.eco_control = 0;
  77.     tx.eco_port    = 0x9F;
  78.     rc=ioctl(h,ECOTRANSMIT,&tx);
  79.  
  80.     if (rc==-1) error("netprint: net error.");
  81.     rp.eco_buffers  = 1;
  82.     rp.eco_rx_group = 0;
  83.     rp.eco_station  = 0;
  84.     rp.eco_net      = 0;
  85.     rp.eco_control  = 0;
  86.     rp.eco_port     = 0x9E;
  87.     rc=ioctl(h,ECOENABLERECEPTION,&rp);
  88.     rp.eco_time_wait= 200;
  89.     rc=ioctl(h,ECOAWAITRECEPTIONTIMED,&rp);
  90.     rc=ioctl(h,ECOBUFFERSTATUS,&rp);
  91.     if (rp.eco_data_length == 0 ) error("Can't find named printer.");
  92.     rp.eco_data_ptr = (int) buffer;
  93.     rc=ioctl(h,ECOBUFFERREAD,&rp);
  94.     if (buffer[0] == 1) error("Printer is bussy.");
  95.     if (buffer[0] == 2) error("netprint: printer is jammed.");
  96.     /* rc=ioctl(h,ECOBUFFERKILL,&rp); */
  97.  
  98.     server.net     = rp.eco_net;
  99.     server.station = rp.eco_station;
  100. }
  101.  
  102.  
  103. void defaultservernumber()
  104. /* Now reads from /dev/cmos to find out defaults */
  105. {
  106.     int n,f;
  107.  
  108.     /* server.net=0;
  109.      * server.station=235;
  110.      * old code now redundant
  111.      */
  112.  
  113.     f=open("/dev/cmos",0,0);
  114.     /* RISC OS PRM Pages 783..786 for CMOS ram mappings   
  115.      * This code tries to read the first five bytes of CMOS ram
  116.      */
  117.  
  118.     n=read(f,buffer+10,5);
  119.     if (n==-1) { 
  120.         printf("netprint: can't read /dev/cmos.  Using 0.235\n");
  121.         server.net=0;
  122.         server.station=235;
  123.         return;
  124.     }
  125.     printf("File handle for /dev/cmos is %d\n",n);
  126.     printf("CMOS ram read results \n");
  127.     printf(" 0  1  2  3  4  5 \n");
  128.     printf("%d %d %d %d %d %d \n",buffer[10],buffer[11],buffer[12],buffer[13],buffer[14]);
  129.     printf("%d \n",buffer[13]);
  130.     if (buffer[13]==0) {
  131.         lseek(f,153L,0);
  132.         n=read(f,buffer+15,5);
  133.         buffer[20]=0;
  134.         printf("Configured server name is %s\n", buffer+14);
  135.         getserverbyname((char *) buffer+14); 
  136.     }
  137.     else
  138.     {
  139.         server.net     = buffer[14];
  140.         server.station = buffer[13];
  141.     }
  142. }
  143.  
  144. void getservernumber(char *c) {
  145.     int n1;
  146.     char *dot;
  147.     dot = index(c,'.');
  148.     n1 = atoi(c);
  149.     if ((dot==NULL) && (n1==0)) {
  150.         /* Find printer via name broadcast */
  151.         getserverbyname(c);
  152.     }
  153.     else {
  154.         if (dot!=NULL) { 
  155.             server.station=atoi(dot+1);
  156.             server.net=n1;
  157.         }
  158.         else {
  159.             server.net=0;
  160.             server.station=n1;
  161.         }
  162.         if ((server.station > 254) | (server.station < 1 )) error("netprint: Bad econet station number."); 
  163.     }
  164. }
  165.  
  166. void sendbuffer(int flags) {
  167.     int rc;
  168.     struct eco_op tx,rp;
  169.     tx.eco_tx_data_ptr = (int) buffer;
  170.     tx.eco_tx_data_length = bufferptr;
  171.     tx.eco_station = server.station;
  172.     tx.eco_net     = server.net;
  173.     tx.eco_control = seq | flags;
  174.     tx.eco_port    = 0xD1;
  175.     rc=ioctl(h,ECOTRANSMIT,&tx);
  176.  
  177.     if (rc==-1) error("Net error.");
  178.     seq = (seq + 1) % 2;
  179.     rp.eco_buffers  = 1;
  180.     rp.eco_rx_group = 0;
  181.     rp.eco_station  = server.station;
  182.     rp.eco_net      = server.net;
  183.     rp.eco_control  = 0;
  184.     rp.eco_port     = 0xD1;
  185.     rc=ioctl(h,ECOENABLERECEPTION,&rp);
  186.     rp.eco_time_wait= 2000;
  187.     rc=ioctl(h,ECOAWAITRECEPTIONTIMED,&rp);
  188.     rc=ioctl(h,ECOBUFFERSTATUS,&rp);
  189.     rc=ioctl(h,ECOBUFFERKILL,&rp);
  190. }
  191.  
  192. void putinbuffer(char c) { /* intersting cast between int and char here! */
  193.     buffer[bufferptr]=c;
  194.     bufferptr+=1;
  195.     if (bufferptr == 80) {
  196.         sendbuffer(0);
  197.         bufferptr = 0;
  198.     }
  199. }
  200.  
  201. int testserver(){
  202.     /* open an RXCB for ps on port &9E
  203.        do a TX on port &9F to ps with data = "PRINT" 01 00
  204.        wait a reasonable time for a reply (1 second?)
  205.        If no reply comes then we can't talk to this server.
  206.        An interesting feature of the protocol is the fact that a server
  207.        must respond to request on its own name (such as Laser etc) and
  208.            to the name "PRINT " as well!!
  209.      */
  210.  
  211.     int rc;
  212.     struct eco_op tx,rp;
  213.     strcpy(buffer,"PRINT ");
  214.     buffer[6]=0x01;
  215.     buffer[7]=0x00;
  216.  
  217.     tx.eco_tx_data_ptr = (int) buffer;
  218.     tx.eco_tx_data_length = 8;
  219.     tx.eco_station = server.station;
  220.     tx.eco_net     = server.net;
  221.     tx.eco_control = 0;
  222.     tx.eco_port    = 0x9F;
  223.     rc=ioctl(h,ECOTRANSMIT,&tx);
  224.  
  225.     if (rc==-1) error("netprint: printer not listening.");
  226.     rp.eco_buffers  = 1;
  227.     rp.eco_rx_group = 0;
  228.     rp.eco_station  = server.station;
  229.     rp.eco_net      = server.net;
  230.     rp.eco_control  = 0;
  231.     rp.eco_port     = 0x9E;
  232.     rc=ioctl(h,ECOENABLERECEPTION,&rp);
  233.     rp.eco_time_wait= 200;
  234.     rc=ioctl(h,ECOAWAITRECEPTIONTIMED,&rp);
  235.     rc=ioctl(h,ECOBUFFERSTATUS,&rp);
  236.     if (rp.eco_data_length == 0 ) error("netprint: no reply from printer");
  237.     rp.eco_data_ptr = (int) buffer;
  238.     rc=ioctl(h,ECOBUFFERREAD,&rp);
  239.     if (buffer[0] == 1) error("Printer is bussy.");
  240.     if (buffer[0] == 2) error("Printer is jammed.");
  241.     return(1);
  242. }
  243.  
  244. int logon(){
  245.     /* open an RXCB for ps on port D1 for the reply
  246.      * Then send the log on request and wait for the reply.
  247.      */
  248.     int rc,junk;
  249.     struct eco_op log,rply;
  250.     junk=0;
  251.  
  252.     rply.eco_buffers  = 1;
  253.     rply.eco_rx_group = 0;
  254.     rply.eco_station  = server.station;
  255.     rply.eco_net      = server.net;
  256.     rply.eco_control  = 0;
  257.     rply.eco_port     = 0xD1;
  258.  
  259.     log.eco_tx_data_ptr = (int) &junk;
  260.     log.eco_tx_data_length = 1;
  261.     log.eco_station = server.station;
  262.     log.eco_net     = server.net;
  263.     log.eco_control = 0x02; /* 0x82 */
  264.     log.eco_port    = 0xD1;
  265.     rc=ioctl(h,ECOTRANSMIT,&log);
  266.     if (rc==-1) return(1);
  267.     rc=ioctl(h,ECOENABLERECEPTION,&rply);
  268.     rply.eco_time_wait = 2000;
  269.     rc=ioctl(h,ECOAWAITRECEPTIONTIMED,&rply);
  270.     rc=ioctl(h,ECOBUFFERSTATUS,&rply);
  271.     rc=ioctl(h,ECOBUFFERKILL,&rply);
  272.     if (rply.eco_data_length=0) return 1 ; /* no reply in time */
  273.     /* assume that we are logged on to the printer server now */
  274.     return 0;
  275. }
  276.  
  277. void logoff() {
  278.     bufferptr+=1;
  279.     sendbuffer(4);
  280. }
  281.  
  282. int main(int argc,char *argv[]) {
  283.     int b;
  284.     h=0;
  285.     seq=1;
  286.  
  287.     if ((h=open("/dev/ecof",0,0))==-1)error("Can't open econet dev.");
  288.     if (claimeconetport(0xD1,h)!=0) error("Can't claim port &D1.");
  289.     if (claimeconetport(0x9E,h)!=0) error("Can't claim port &9E.");
  290.     if (claimeconetport(0x9F,h)!=0) error("Can't claim port &9F.");
  291.     if (argc==2)  
  292.         getservernumber(argv[1]);
  293.     else
  294.         defaultservernumber();
  295.     printf("Server is found at %d.%d\n",server.net,server.station);
  296.     /* error("Debugging\n");  */
  297.     if (testserver()) {
  298.         if (logon()!=0) error("Can't log on to server.");
  299.         while ((b=getchar())!= EOF) 
  300.             putinbuffer(b); 
  301.         logoff(); 
  302.     }
  303.     quithandler();
  304.     return 0;
  305. } /* main */
  306.